package com.kds.smarthome.quartz;

import com.alibaba.fastjson.JSON;
import com.kds.smarthome.entity.QuartzJob;
import com.kds.smarthome.entity.QuartzJobLog;
import com.kds.smarthome.service.QuartzJobLogService;
import com.kds.smarthome.service.QuartzJobService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

/**
 * 支持SpringEL表达式的定时任务执行器
 */
@Slf4j
@Component
@DisallowConcurrentExecution
public class SpringElJob extends QuartzJobBean {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Autowired
    private QuartzJobService jobService;
    
    @Autowired
    private QuartzJobLogService jobLogService;
    
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        String jobId = context.getJobDetail().getKey().getName();
        String jobGroup = context.getJobDetail().getKey().getGroup();
        
        QuartzJob quartzJob = jobService.getJobById(jobId);
        if (quartzJob == null) {
            log.error("任务不存在，JobID: {}, JobGroup: {}", jobId, jobGroup);
            return;
        }
        
        // 创建任务日志
        QuartzJobLog jobLog = new QuartzJobLog();
        jobLog.setJobId(jobId);
        jobLog.setJobName(quartzJob.getJobName());
        jobLog.setJobGroup(jobGroup);
        jobLog.setSpringElExpression(quartzJob.getSpringElExpression());
        jobLog.setJobData(quartzJob.getJobData());
        jobLog.setStartTime(new Date());
        
        // 更新任务执行信息
        quartzJob.setLastExecuteTime(new Date());
        quartzJob.setExecuteCount(quartzJob.getExecuteCount() == null ? 1 : quartzJob.getExecuteCount() + 1);
        
        Object result = null;
        try {
            // 解析任务参数
            Map<String, Object> params = null;
            if (quartzJob.getJobData() != null && !quartzJob.getJobData().isEmpty()) {
                params = JSON.parseObject(quartzJob.getJobData(), Map.class);
            }
            
            // 创建SpringEL表达式解析器
            ExpressionParser parser = new SpelExpressionParser();
            Expression expression = parser.parseExpression(quartzJob.getSpringElExpression());
            
            // 创建评估上下文
            StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
            
            // 设置BeanResolver
            evaluationContext.setBeanResolver(new org.springframework.context.expression.BeanFactoryResolver(applicationContext));
            
            // 添加上下文变量
            if (params != null) {
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    evaluationContext.setVariable(entry.getKey(), entry.getValue());
                }
            }
            
            // 执行表达式
            result = expression.getValue(evaluationContext);
            
            // 更新执行状态
            quartzJob.setExecuteStatus(1);
            jobLog.setStatus(1);
            jobLog.setResult(result != null ? result.toString() : "");
            
            log.info("任务执行成功, JobID: {}, JobName: {}, Result: {}", jobId, quartzJob.getJobName(), result);
        } catch (Exception e) {
            // 更新执行状态
            quartzJob.setExecuteStatus(0);
            jobLog.setStatus(0);
            jobLog.setErrorMessage(e.getMessage());
            
            log.error("任务执行失败, JobID: {}, JobName: {}, Error: {}", jobId, quartzJob.getJobName(), e.getMessage(), e);
        } finally {
            // 更新任务信息
            jobService.updateJob(quartzJob);
            
            // 设置结束时间并计算执行时间
            jobLog.setEndTime(new Date());
            if (jobLog.getStartTime() != null && jobLog.getEndTime() != null) {
                jobLog.setExecuteTime(jobLog.getEndTime().getTime() - jobLog.getStartTime().getTime());
            }
            
            // 保存任务日志
            jobLogService.saveJobLog(jobLog);
        }
    }
} 